package Test;

class Product {
    // 产品数量
    private int count = 0;

    // 添加产品 (count ++)
    public synchronized void produce() throws InterruptedException {
        System.out.println(Thread.currentThread().getName() + " 进入 produce 方法");

        // 如果产品数量大于 0, 则不需要添加产品
        if (count > 0) {
            System.out.println(Thread.currentThread().getName() + ": 产品数量大于 0, 进入等待...");
            this.wait();
        }

        // 添加产品
        count ++;
        System.out.println(Thread.currentThread().getName() + " 添加产品, 剩余 " + count + " 件产品");

        // 添加完产品后, 唤醒其他线程
        System.out.println(Thread.currentThread().getName() + " 唤醒其他线程");
        this.notifyAll();
    }

    // 消费产品(count --)
    public synchronized void consume() throws InterruptedException {
        System.out.println(Thread.currentThread().getName() + " 进入 consume 方法");

        // 如果产品数量小于等于 0, 则无法消费产品
        if (count <= 0) {
            System.out.println(Thread.currentThread().getName() + ": 产品数量小于等于 0, 进入等待...");
            this.wait();
        }

        // 消费产品
        count --;
        System.out.println(Thread.currentThread().getName() + " 消费产品, 剩余 " + count + " 件产品");

        // 消费完产品后, 唤醒其他线程
        System.out.println(Thread.currentThread().getName() + " 唤醒其他线程");
        this.notifyAll();
    }
}
public class TestDemo16 {
    public static void main(String[] args) {
        Product product = new Product();

        // 创建生产者的任务类对象
        Runnable produceRunnable = new Runnable() {
            // 要执行的任务
            public void run() {
                for (int i = 0; i < 10; i++) {
                    try {
                        product.produce();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        // 创建消费者的任务类对象
        Runnable consumeRunnable = new Runnable() {
            // 要执行的任务
            public void run() {
                for (int i = 0; i < 10; i++) {
                    try {
                        product.consume();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        Thread producer1 = new Thread(produceRunnable, "Producer 1");
        producer1.start();
        Thread producer2 = new Thread(produceRunnable, "Producer 2");
        producer2.start();
        Thread consumer1 = new Thread(consumeRunnable, "Consumer 1");
        consumer1.start();
        Thread consumer2 = new Thread(consumeRunnable, "Consumer 2");
        consumer2.start();
    }
}
